package com.org.lg.service;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.jpay.ext.kit.PaymentKit;
import com.jpay.ext.kit.StrKit;
import com.jpay.ext.kit.ZxingKit;
import com.jpay.util.StringUtils;
import com.jpay.weixin.api.WxPayApi;
import com.jpay.weixin.api.WxPayApi.TradeType;
import com.jpay.weixin.api.WxPayApiConfig;
import com.jpay.weixin.api.WxPayApiConfigKit;
import com.org.lg.api.WxPayService;
import com.org.lg.bean.PayConfig;
import com.org.lg.constant.Constant;
import com.org.lg.constant.PayCodeType;
import com.org.lg.model.H5PayModel;
import com.org.lg.model.H5PayModel.H5;
import com.org.lg.model.WechatPayModel;
import com.org.lg.model.WxApiResult;
import com.org.lg.model.WxTradeRefundModel;

import lombok.extern.java.Log;
@Log
@Service
public class WxPayServiceImpl  implements WxPayService {
	
	@Override
	public WxApiResult scanPay(Map<String, String> param) {
		Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig()
		.setBody("微信支付")
		.setTradeType(TradeType.NATIVE)
		.setSpbillCreateIp("")
		.setOutTradeNo(String.valueOf(System.currentTimeMillis()))
		.build();
		params.putAll(param);
		String xmlResult = WxPayApi.pushOrder(false,params);
        log.info("prepay_xml>>>"+xmlResult);
        Map<String, String> payResult = PaymentKit.xmlToMap(xmlResult);
        String return_code = payResult.get(Constant.RESULT_CODE);
        String result_code = payResult.get(Constant.RESULT_CODE);
        String return_msg = payResult.get(Constant.RETURN_MSG);
        if (!PaymentKit.codeIsOK(return_code)) {//失败
             return WxApiResult.RES(PayCodeType.SCAN_FAIL.getCode());
        }
        if (!PaymentKit.codeIsOK(result_code)) {//失败
        	 return WxApiResult.RES(PayCodeType.SCAN_FAIL.getCode());
        }
        //生成预付订单success
        String qrCodeUrl = payResult.get(Constant.CODE_URL);
        String name = "payQRCode2.png";
        Boolean encode = ZxingKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200,
                "E://"+File.separator+name);
        if (encode) {
        	 return WxApiResult.RES(PayCodeType.SCAN_SUCCESS.getCode());
	    }
        return WxApiResult.RES(PayCodeType.SCAN_FAIL.getCode());
	}

	@Override
	public boolean verifyNotify(Map<String, String> params) {
		return PaymentKit.verifyNotify(params,PayConfig.WxPay.partnerKey);
	}

	@Override
	public WxApiResult h5Pay(HttpServletResponse response,H5PayModel h5PayModel) {
		WxApiResult res=checkParam(h5PayModel);
		if(!res.ckSuccess()) {
			return res;
		}
		H5 h5_info = new H5();
		h5_info.setType(Constant.WAP);
		//此域名必须在商户平台--"产品中心"--"开发配置"中添加
		h5_info.setWap_url("https://pay.qq.com");
		h5_info.setWap_name("微信支付");
		h5PayModel.setH5_info(h5_info);
		WxPayApiConfig payConfig=WxPayApiConfigKit.getWxPayApiConfig()
		.setAttach(h5PayModel.getAttach())
		.setBody(h5PayModel.getBody())
		.setSpbillCreateIp(h5PayModel.getIp())
		.setTradeType(TradeType.MWEB)
		.setNotifyUrl(h5PayModel.getNotifyUrl())
		.setSceneInfo(h5_info.toString())
		.setTotalFee(h5PayModel.getTotalFee())
		.setOutTradeNo(h5PayModel.getOutTradeNo());
		if(StringUtils.isNotBlank(h5PayModel.getNotifyUrl())) {
			payConfig.setNotifyUrl(h5PayModel.getNotifyUrl());
		}
		String xmlResult = WxPayApi.pushOrder(false,payConfig.build());
        log.info(xmlResult);
		Map<String, String>  payResult = PaymentKit.xmlToMap(xmlResult);
		String return_code = payResult.get(Constant.RESULT_CODE);
	    String result_code = payResult.get(Constant.RESULT_CODE);
	    String return_msg  = payResult.get(Constant.RETURN_MSG);
		if (!PaymentKit.codeIsOK(return_code)) {
			log.info("return_code>"+return_code+" return_msg>"+return_msg);
			return WxApiResult.RES(return_code);
		}
		if (!PaymentKit.codeIsOK(result_code)) {
			log.info("result_code>"+result_code+" return_msg>"+return_msg);
			return WxApiResult.RES(return_code);
		}
		String prepay_id = payResult.get(Constant.PREPAY_ID);
		String mweb_url = payResult.get(Constant.MWEB_URL);
		log.info("prepay_id:"+prepay_id+" mweb_url:"+mweb_url);
		try {
			response.sendRedirect(mweb_url);
		} catch (IOException e) {
			e.printStackTrace();
			return WxApiResult.RES(return_code);
		}
		return WxApiResult.RES(return_code);
	}

	@Override
	public WxApiResult wechatPay(WechatPayModel payModel) {
		WxApiResult res=checkParam(payModel);
		if(!res.ckSuccess()) {
			return res;
		}
		if (StrKit.isBlank(payModel.getOpenId())) {
			return WxApiResult.RES(40003);
		}
		WxPayApiConfig payConfig=WxPayApiConfigKit.getWxPayApiConfig()
		.setAttach(payModel.getAttach())
		.setBody(payModel.getBody())
		.setOpenId(payModel.getOpenId())
		.setSpbillCreateIp(payModel.getIp())
		.setTotalFee(payModel.getTotalFee())
		.setTradeType(TradeType.JSAPI)
		.setOutTradeNo(String.valueOf(System.currentTimeMillis()));
		if(StringUtils.isNotBlank(payModel.getNotifyUrl())) {
			payConfig.setNotifyUrl(payModel.getNotifyUrl());
		}
		String xmlResult = WxPayApi.pushOrder(false,payConfig.build());
		Map<String, String> resultMap = PaymentKit.xmlToMap(xmlResult);
		String return_code = resultMap.get(Constant.RETURN_CODE);
		String return_msg = resultMap.get(Constant.RETURN_MSG);
		if (!PaymentKit.codeIsOK(return_code)) {
			log.warning(return_msg);
			return WxApiResult.RES(521001);
		}
		String result_code = resultMap.get(Constant.RESULT_CODE);
		if (!PaymentKit.codeIsOK(result_code)) {
			log.warning(return_msg);
			return WxApiResult.RES(521001);
		}
		// 以下字段在return_code 和result_code都为SUCCESS的时候有返回
		String prepay_id = resultMap.get(Constant.PREPAY_ID);
		Map<String, String> packageParams = PaymentKit.prepayIdCreateSign(prepay_id);
		String jsonStr = JSON.toJSONString(packageParams);
		return WxApiResult.RES(jsonStr);
	}
	
	
	@SuppressWarnings("unused")
	private  <T extends WechatPayModel> WxApiResult checkParam(T t) {
		
		if (null==t.getTotalFee()) {
			return WxApiResult.RES(40003);
		}
		
		if (StrKit.isBlank(t.getIp())) {
			return WxApiResult.RES(41011);
		}
		
		if (StrKit.isBlank(t.getOutTradeNo())) {
			return WxApiResult.RES(41011);
		}
		return WxApiResult.RES(0);
	}

	@Override
	public WxApiResult tradeRefund(WxTradeRefundModel refundModel) {
		if (StrKit.isBlank(refundModel.getOutTradeNo()) && StrKit.isBlank(refundModel.getTransactionId())) {
			return WxApiResult.RES(521002);
		}
		Map<String, String> params = new HashMap<String, String>();
		params.put("appid", PayConfig.WxPay.appId);
		params.put("mch_id", PayConfig.WxPay.mchId);
		params.put("nonce_str", System.currentTimeMillis()+"");
		if (StrKit.notBlank(refundModel.getTransactionId())) {
			params.put("transaction_id", refundModel.getTransactionId());
		}else {
			params.put("out_trade_no", refundModel.getOutTradeNo());
		}
		params.put("out_refund_no", System.currentTimeMillis()+"");
		params.put("total_fee",refundModel.getTotalFee());
		params.put("refund_fee", refundModel.getRefundFee());
		params.put("sign", PaymentKit.createSign(params, PayConfig.WxPay.partnerKey));
		String refund = WxPayApi.orderRefund(false, params , PayConfig.WxPay.certPath, PayConfig.WxPay.mchId);
		return WxApiResult.RES(refund);
	}
}
